package ig.metrica.rentabilidad;

import ig.metrica.ejb.html.GenerarHTML;
import ig.metrica.riesgo.ZonaDTO;
import java.rmi.RemoteException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;

import javax.ejb.FinderException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import ig.finanzas.Contrato;
import ig.finanzas.ContratoPK;
import ig.finanzas.ContratoSimpleHome;
import ig.finanzas.Flujo;
import ig.finanzas.ManejadorFlujos;
import ig.finanzas.Moneda;
import ig.finanzas.MonedaHome;
import ig.finanzas.MonedaPK;
import ig.finanzas.PosicionAccionHome;
import ig.finanzas.PosicionEspecieHome;
import ig.util.ConexionServer;
import ig.util.ejb.IGSessionBean;
import ig.util.excepciones.DatoInvalidoExcepcion;
import ig.util.excepciones.LogicaExcepcion;
import java.util.ArrayList;

public class CalculoRentabilidadBean extends IGSessionBean implements CalculoRentabilidadBussines {
    private GenerarHTML generarHTML = null;
    private Collection<ZonaDTO> collection=new ArrayList();
    public void setGenerarHTML(GenerarHTML generarHTML) {
        this.generarHTML = generarHTML;
    }

	public void ejbCreate(){}
	
	public Moneda getMoneda(MonedaPK monedaPK) throws NamingException, FinderException{

		try {
			Properties prop = new Properties();
			prop.put( Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
			String Sockec = new ConexionServer().getSocketServer();
			prop.put( Context.PROVIDER_URL, Sockec);
			
			InitialContext ctx = new InitialContext(prop);
			
			MonedaHome home = (MonedaHome)ctx.lookup("ig.finanzas.Moneda");
			Moneda moneda = home.findByPrimaryKey(monedaPK);
			
			return moneda;
		} catch (RemoteException e) {
                    System.out.println("ERROR:"+e.toString());
		} 
		return null;
				
	}
	
	/**
	 * Efectua el analisis de rentabilidad
	 * @param fechaInicio
	 * @param fechaFin
	 * @throws DatoInvalidoExcepcion Si alguna de las fechas suministradas es nula, 
	 * o si la fecha final es menor que la inicial. 
	 * @throws SQLException Si se presento un error al conectarse u obtener los datos de la base de datos.
	 * @throws NamingException Si se presento un error con JNDI.
	 * @throws FinderException Si no se pueden encontrar los objetos en el servidor de aplicaciones.
	 * @throws LogicaExcepcion Si no hay valores historicos para las monedas suficientes para establecer un valor vigente.
	 */
	public void efectuarCalculo(Date fechaInicio, Date fechaFin, int mTipoValoracion) throws NamingException, SQLException, FinderException, DatoInvalidoExcepcion, LogicaExcepcion{
                
		if (fechaInicio == null){
                        generarHTML.println("La fecha de inicio es nula.");
			throw new DatoInvalidoExcepcion("La fecha de inicio es nula.");
                }
		
		if (fechaFin == null){
                        generarHTML.println("La fecha de fin es nula.");
			throw new DatoInvalidoExcepcion("La fecha de fin es nula.");
                }
		
		if (fechaFin.getTime() <= fechaInicio.getTime()){
                        generarHTML.println("La fecha final es menor que la inicial.");
			throw new DatoInvalidoExcepcion("La fecha final es menor que la inicial.");
                }
		
		Properties prop = new Properties();
		prop.put( Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
                String Sockec = new ConexionServer().getSocketServer();
                prop.put( Context.PROVIDER_URL, Sockec);


		conn = getConexion("METRICADB");
		Collection contratos;
		
		Iterator i;
		
		//Se borra la informacion de las tablas donde se va a almacenar la informacion.
		//Statement stmt1 = conn.createStatement();
		//stmt1.executeUpdate("DELETE FROM CALCULOSRENTABILIDADCONTRATOS");
		//if (stmt1!=null)
		//	stmt1.close();
                
                if (mTipoValoracion == 1){
//                    pstmt1 = conn.prepareStatement("SELECT VALORAFECHA1, VALORAFECHA2 FROM ADICIONALESCONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");
                    pstmt1 = conn.prepareStatement("SELECT VALORAFECHA1, VALORAFECHA2 FROM ADICONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");                    
                }else {
//                    pstmt1 = conn.prepareStatement("SELECT VALORATIRFECHA1 AS VALORAFECHA1, VALORATIRFECHA2 AS VALORAFECHA2 FROM ADICIONALESCONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");                    
                    pstmt1 = conn.prepareStatement("SELECT VALORATIRFECHA1 AS VALORAFECHA1, VALORATIRFECHA2 AS VALORAFECHA2 FROM ADICONTRATOSRENTABILIDAD  WHERE IDCONTRATO=?");                    
                }
                
		
                
//		pstmt1 = conn.prepareStatement("SELECT VALORAFECHA1, VALORAFECHA2 FROM ADICIONALESCONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");
		//pstmt2 = conn.prepareStatement("INSERT INTO CALCULOSRENTABILIDADCONTRATOS VALUES(?,?,?,?,?,?)");

		InitialContext ctx = new InitialContext(prop);
		
		/*
		 * ----------------------------------------------------------------------------------------------------------------------------
		 * ContratosSimples.
		*/
	
		ContratoSimpleHome home1 = (ContratoSimpleHome)ctx.lookup("ig.finanzas.ContratoSimple");
		PosicionEspecieHome home2 = (PosicionEspecieHome)ctx.lookup("ig.finanzas.PosicionEspecie");
		PosicionAccionHome home3 = (PosicionAccionHome)ctx.lookup("ig.finanzas.PosicionAccion");
		
		try {
			contratos = home1.findAll();
			contratos.addAll( home2.findAll() );
			contratos.addAll( home3.findAll() );
			i = contratos.iterator();
                        generarHTML.println("Procesando "+contratos.size()+" Contratos");
                        pstmt2 = conn.prepareStatement("INSERT INTO CALCULOSRENTABILIDADCONTRATOS VALUES(?,?,?,?)");
			while (i.hasNext()){
				//Recorro los contratos simples
				Contrato contrato = (Contrato)i.next();
				ManejadorFlujos flujos = contrato.flujosEntre(fechaInicio, false, fechaFin, true);
				
				pstmt1.setLong(1, ((ContratoPK)contrato.getPrimaryKey()).getIdInterna() );
				ResultSet r1 = pstmt1.executeQuery();
				
				Double valoracionfinal = null;
				
				if (r1.next()){
                                    String temp = r1.getString("VALORAFECHA1");
                                    Double temp1 = new Double(temp).doubleValue() ;
                                    if (temp1!=0)
                                        flujos.adicionarFlujo( new Flujo(fechaInicio, new Double(temp).doubleValue()*-1, 0, 0, true,false) );

                                    temp = r1.getString("VALORAFECHA2");
                                    Double temp2 = new Double(temp).doubleValue() ;
                                    if (temp2!=0){					
                                        flujos.adicionarFlujo( new Flujo(fechaFin, new Double(temp).doubleValue(), 0, 0, true,false) );
//						valoracionfinal = new Double(temp);
                                    }
                                    //}//ojo cambiada por la que esta despue del execute de la linea 182

                                    if (flujos.numeroFlujos()==0){
                                            continue;
                                    }

                                    if (valoracionfinal==null)
                                            valoracionfinal = new Double( flujos.sumaFlujosPositivos() );

                                    int numdias = (int) ((flujos.fechaUltimoFlujo().getTime()-flujos.fechaPrimerFlujo().getTime())/(24*60*60*1000));
                                    double tirFlujoCaja = flujos.tir();	
                                    Moneda moneda = getMoneda(contrato.getMonedaPK());
                                    
                                    double cambio = moneda.obtenerValorVigenteA( flujos.fechaUltimoFlujo() );
    //				double valoracion = valoracionfinal.doubleValue() * cambio ;
                                    double valoracion = valoracionfinal.doubleValue() ;	
                                    
                                    pstmt2.setLong(1, ((ContratoPK)contrato.getPrimaryKey()).getIdInterna() );
                                    pstmt2.setDouble(2, tirFlujoCaja);
                                    pstmt2.setInt(3, numdias);
                                    pstmt2.setDouble(4, valoracion );
                                    pstmt2.executeUpdate();
                                    pstmt2.clearParameters();
                                }
                        }
//                } catch (SQLException e) {
//                    e.printStackTrace();
		}catch (RemoteException e) {
                    e.printStackTrace();
		}
                closeAll();
	}	
    public void closeAll(){
        try {if(conn != null && !conn.isClosed())conn.close();
        } catch (SQLException e){}
        try {if(pstmt1!=null)pstmt1.close();   
        } catch (Exception e) {}
        try {if(pstmt2!=null)pstmt2.close();
        } catch (Exception e) {}
        try {if(pstmt3!=null)pstmt3.close();
        } catch (Exception e) {}
        try {if(pstmt4!=null)pstmt4.close();
        } catch (Exception e) {}
        try {if(pstmt5!=null)pstmt5.close();                
        } catch (Exception e) {}
    }
    
    public void setZonas(Collection<ZonaDTO> collection) {
        this.collection=collection;
    }
}